{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本部分将通过提供使用编程语言实现高频交易（HFT）系统的指南，为您提供实践经验。我们将从高频交易中最常用的语言——C++开始我们的旅程，然后继续介绍Java及其虚拟机。我们将解释Python如何使用高频交易库。本专栏的结尾将描述现场可编程门阵列（FPGA）如何减少从报价到交易的延迟，并讨论加密货币领域的高频交易。\n",
    "\n",
    "本部分包含以下章节：\n",
    "\n",
    "- 第8章 C++——追求微秒级延迟\n",
    "- 第9章 低延迟系统的Java和JVM\n",
    "- 第10章 Python——解释型但支持高性能\n",
    "- 第11章 高频FPGA和加密货币"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第8章 C++——追求微秒级延迟"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本章将讨论C++的一些特性和构造。在开始之前需要说明的是，涵盖现代C++（C++11/14/17）的大部分内容超出了单章（通常也是单本专栏）的范围，因此我们将重点关注对开发、维护和改进多线程及超低运行时延迟的高频交易（HFT）应用程序重要的几个方面。在开始深入本章之前，建议您精通C++。我们推荐几本相关书籍，如Bjarne Stroustrup所著的《Programming: Principles and Practice Using C++》。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们将首先研究现代C++内存模型，该模型规定了多线程环境中共享内存交互的工作方式，然后探讨静态分析，这是应用程序开发、测试和维护的重要方面。<br/>\n",
    "接着，我们将深入研究如何针对运行时性能优化应用程序，最后专门用一个章节来讨论模板，这对顶级高频交易生态系统至关重要。\n",
    "\n",
    "本章将涵盖以下主题：\n",
    "- C++内存模型\n",
    "- 消除运行时决策\n",
    "- 动态内存分配\n",
    "- 用于减少运行时的模板\n",
    "- 静态分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "到本章结束时，您将能够为高频交易系统优化C++代码。最后，我们将回顾一个行业用例，讨论用于构建外汇（FX）高频对冲基金的技术。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![8.1](./images/8.1.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先，让我们谈谈C++内存模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## C++14/17内存模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本节将探讨现代C++（11、14和17）内存模型的定义和规范。我们将研究它是什么、多线程应用程序为何需要它，以及C++内存模型的重要原则。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 什么是内存模型？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**内存模型**，又称内存一致性模型，规定了与共享内存交互的多线程应用程序的允许行为和预期行为。内存模型是共享内存系统并发语义的基础。如果有两个并发程序，一个对共享内存空间进行写入，另一个进行读取，内存模型将定义对于任意读写组合，读操作允许返回的值的集合。\n",
    "\n",
    "内存模型（无论是C++的还是其他的）的实现必须受内存模型指定规则的约束，因为如果结果无法从读写顺序推断出来，那么它就不是一个明确的内存模型。思考内存模型所实施限制的另一种方式是，这些限制定义了编译器、处理器和架构（内存）允许的指令重排序。大多数关于内存模型的研究都试图最大化编译器、处理器和架构优化的自由度。\n",
    "\n",
    "即使优化变得越来越复杂，它们也必须保持开发者想要实现的语义，绝不能打破内存模型的约束。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在，让我们正式定义几个术语。\n",
    "\n",
    "- 源代码顺序: 这是程序员用所选编程语言指定的指令和内存操作的顺序，是编译器编译代码之前存在的代码或指令集。\n",
    "- 程序顺序: 这是源代码编译后将在CPU上执行的机器代码中的指令和内存操作的顺序。这里的指令和/或内存操作的顺序可能不同，因为如前所述，编译器会将指令重排序作为优化过程的一部分来尝试优化。\n",
    "- 执行顺序: 这是在CPU上实际执行指令和内存引用的顺序。这与编译后的程序顺序不同，因为在此阶段，CPU和一般架构允许对编译器生成的机器代码中的指令进行重排序。此处的优化取决于特定CPU及其架构的内存模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在我们将讨论内存模型的必要性。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 为什么需要内存模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "让我们讨论为什么我们完全需要一个定义良好的内存模型。**根本原因**在于，我们编写的代码与编译过程后的输出代码并不完全相同，也与在硬件上运行的代码不同。现代编译器和CPU允许乱序执行指令，以最大化性能和资源利用率。\n",
    "\n",
    "在单线程环境中，这无关紧要，但在运行于多核（多处理器）架构上的多线程环境中，不同线程尝试读取和写入共享内存位置会导致竞态条件，并且在存在指令重排序的情况下可能导致未定义和意外的行为。\n",
    "\n",
    "正如我们在第4章“高频交易系统基础——从硬件到操作系统”中所见，调度和上下文切换是非确定性的。它们可以被控制，但当上下文切换发生在极其特定的位置时，优化可能导致指令执行和内存访问的顺序因事件序列不同而产生不同的结果。\n",
    "\n",
    "内存模型为优化编译器在应用优化时提供了高度的自由度。内存模型规定了使用同步原语（互斥锁、锁、同步块、屏障等）的同步屏障，我们在前一章第7章“高频交易优化——日志记录、性能和网络”中已经见过这些原语。当共享变量发生变化时，当"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "name": "C++17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
